package com.wenlin.myproduction.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.wenlin.myproduction.R;

public class FaceTabButton extends View {
    private static final int STATE_NORMAL = 0;
    private static final int STATE_PRESSED = 1;
    private static final int STATE_SELECTED = 2;
    private static final float MIN_RATIO = 0.9f;
    private static final float MAX_RATIO = 1.1f;
    private static final int ANIM_DUR = 300;
    private boolean isBad;
    private Paint paint, paintBitmap;
    private TextPaint textPaint;
    private Rect rect;
    private Bitmap bitmapNormalGood, bitmapSelectedGood;
    private Bitmap bitmapNormalBad, bitmapSelectedBad;
    private ValueAnimator valueAnimator;
    private float valueFactor = 1;
    private int state;//状态
    private int picWidth = (int) dpToPx(120);
    private int picHeight = (int) dpToPx(40);
    private int viewWidth = (int) (picWidth * MAX_RATIO);
    private int viewHeight = (int) (picHeight * MAX_RATIO);
    private float lastX, lastY;
    private OnSelectedListener listener;
    private String title;
    @ColorInt
    private int colorNormal = ContextCompat.getColor(getContext(), R.color.myText);
    @ColorInt
    private int colorSelected = Color.parseColor("#FFAD317A");
    private boolean locked;//是否锁定住不让点击

    public FaceTabButton(Context context) {
        this(context, null);
    }

    public FaceTabButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);

        paintBitmap = new Paint();
        paintBitmap.setAntiAlias(true);
        paintBitmap.setStyle(Paint.Style.FILL_AND_STROKE);

        textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(true);
        textPaint.setTextSize(dpToPx(17));

        rect = new Rect();
        bitmapNormalGood = BitmapFactory.decodeResource(getResources(), R.mipmap.common_btn_good_normal);
        bitmapSelectedGood = BitmapFactory.decodeResource(getResources(), R.mipmap.common_btn_good_selected);
        bitmapNormalBad = BitmapFactory.decodeResource(getResources(), R.mipmap.common_btn_bad_normal);
        bitmapSelectedBad = BitmapFactory.decodeResource(getResources(), R.mipmap.common_btn_bad_selected);

        bitmapNormalGood = getBitmapWithTargetWidthHeight(bitmapNormalGood, picWidth, picHeight);
        bitmapSelectedGood = getBitmapWithTargetWidthHeight(bitmapSelectedGood, picWidth, picHeight);
        bitmapNormalBad = getBitmapWithTargetWidthHeight(bitmapNormalBad, picWidth, picHeight);
        bitmapSelectedBad = getBitmapWithTargetWidthHeight(bitmapSelectedBad, picWidth, picHeight);

        title = getResources().getString(R.string.good);
    }

    public void setLocked(boolean locked) {
        this.locked = locked;
        invalidate();
    }

    public void setOnSelectedListener(OnSelectedListener listener) {
        this.listener = listener;
    }

    public void setStateSelected() {
        state = STATE_SELECTED;
        invalidate();
    }

    public void setBad(boolean isBad) {
        this.isBad = isBad;
        title = getResources().getString(R.string.bad);
        invalidate();
    }

    public void resetAnimAndUnselected() {
        state = STATE_NORMAL;
        if (valueAnimator != null && valueAnimator.isRunning()) {
            valueAnimator.cancel();
            valueAnimator = null;
        }
        valueFactor = 1;
        invalidate();
    }

    public void pressOut() {
        startScaleBigAnimation();
    }

    public void pressIn() {
        startScaleSmallAnimation();
    }

    private void startScaleBigAnimation() {
        if (valueAnimator != null && valueAnimator.isRunning()) {
            valueAnimator.cancel();
            valueAnimator = null;
        }
        valueAnimator = ValueAnimator.ofFloat(valueFactor, MAX_RATIO, 1);
        valueAnimator.addUpdateListener(animation -> {
            valueFactor = (float) animation.getAnimatedValue();
            invalidate();
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (listener != null) listener.onSelectedStart();
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                state = STATE_SELECTED;
                if (listener != null) listener.onSelectedEnd();
            }

            @Override
            public void onAnimationCancel(@NonNull Animator animation) {

            }

            @Override
            public void onAnimationRepeat(@NonNull Animator animation) {

            }
        });
        int duration = (int) ((MAX_RATIO - valueFactor + MAX_RATIO - 1) / (1 - MIN_RATIO) * ANIM_DUR);
        valueAnimator.setDuration(ANIM_DUR);
        valueAnimator.setRepeatCount(0);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.start();
    }

    private void startScaleSmallAnimation() {
        if (valueAnimator != null && valueAnimator.isRunning()) {
            valueAnimator.cancel();
            valueAnimator = null;
        }
        valueAnimator = ValueAnimator.ofFloat(1, MIN_RATIO);
        valueAnimator.addUpdateListener(animation -> {
            valueFactor = (float) animation.getAnimatedValue();
            invalidate();
        });
        valueAnimator.setDuration(ANIM_DUR);
        valueAnimator.setRepeatCount(0);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.start();
    }

    private Bitmap getBitmapByState() {
        if (state == STATE_NORMAL) {
            return isBad ? bitmapNormalBad : bitmapNormalGood;
        } else {
            return isBad ? bitmapSelectedBad : bitmapSelectedGood;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        canvas.drawColor(Color.RED);
        canvas.save();
        canvas.scale(valueFactor, valueFactor, viewWidth / 2f, viewHeight / 2f);
        canvas.drawBitmap(getBitmapByState(), viewWidth / 2f - getBitmapByState().getWidth() / 2f, viewHeight / 2f - getBitmapByState().getHeight() / 2f, paintBitmap);
        textPaint.getTextBounds(title, 0, title.length(), rect);
        textPaint.setColor(state == STATE_NORMAL ? colorNormal : colorSelected);
        canvas.drawText(title, viewWidth * 7 / 12f - rect.width() / 2f, viewHeight / 2f - (rect.bottom + rect.top) / 2f, textPaint);
        canvas.restore();
//        if (viewWidth == 0) {
//            viewWidth = bitmapNormal.getWidth();
//            viewHeight = bitmapNormal.getHeight();
//            requestLayout();
//        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!locked) {
            float x = event.getX();
            float y = event.getY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN://按下手指记录x坐标
                    lastX = x;
                    lastY = y;
                    state = STATE_PRESSED;
                    startScaleSmallAnimation();
                    return true;
                case MotionEvent.ACTION_UP://手指抬起时
                    float dx = x - lastX;
                    float dy = y - lastY;
                    state = STATE_PRESSED;
                    startScaleBigAnimation();
                    performClick();
                    return true;
                default:
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));
    }

    /**
     * 获取宽或者高
     *
     * @param measureSpec 测量单位
     * @param isWidSpec   是宽还是高
     * @return 所求
     */
    private int measure(int measureSpec, boolean isWidSpec) {
        int result;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = isWidSpec ? viewWidth : viewHeight;
            if (mode == MeasureSpec.AT_MOST) result = Math.min(result, size);
        }
        return result;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (bitmapNormalGood != null && !bitmapNormalGood.isRecycled()) {
            bitmapNormalGood.recycle();
            bitmapNormalGood = null;
        }
        if (bitmapSelectedGood != null && !bitmapSelectedGood.isRecycled()) {
            bitmapSelectedGood.recycle();
            bitmapSelectedGood = null;
        }
        if (bitmapNormalBad != null && !bitmapNormalBad.isRecycled()) {
            bitmapNormalBad.recycle();
            bitmapNormalBad = null;
        }
        if (bitmapSelectedBad != null && !bitmapSelectedBad.isRecycled()) {
            bitmapSelectedBad.recycle();
            bitmapSelectedBad = null;
        }
    }

    /**
     * 生成新的Bitmap图片
     *
     * @return 所求
     */
    private Bitmap getBitmapWithTargetWidthHeight(Bitmap bitmap, float newWidth, float newHeight) {
        Matrix matrix = new Matrix();
        int width = bitmap.getWidth();//获取图片本身的宽
        int height = bitmap.getHeight();//获取图片本身的高
        float scaleRatioOfWidth = newWidth / (width > 0 ? width : newWidth);//宽度缩放比
        float scaleRatioOfHeight = newHeight / (height > 0 ? height : newHeight);//高度缩放比
        matrix.postScale(scaleRatioOfWidth, scaleRatioOfHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    }

    /**
     * 转化长度单位
     *
     * @param dp dp长度
     * @return 对应的px长度
     */
    private float dpToPx(float dp) {
        float scale = getResources().getDisplayMetrics().density;
        return dp * scale;
    }

    public interface OnSelectedListener {
        void onSelectedStart();

        void onSelectedEnd();
    }
}
